/*
 * @ProjectName: 编程学习
 * @Copyright:   2019 HangZhou Ashe Dev, Ltd. All Right Reserved.
 * @address:     https://yiyuery.github.io/NoteBooks/
 * @date:        2020/2/24 12:03 上午
 * @description: 本内容仅限于编程技术学习使用，转发请注明出处.
 */
package com.yi.yier.boot.autoconfigure.codegenerator.gen.extend.impl;

import com.google.common.base.CaseFormat;
import com.yi.yier.boot.autoconfigure.codegenerator.common.GenCodeParam;
import com.yi.yier.boot.autoconfigure.codegenerator.common.PropertyConstant;
import com.yi.yier.boot.autoconfigure.codegenerator.gen.extend.ITemplateContextBuilder;
import com.yi.yier.boot.autoconfigure.codegenerator.common.PropertiesLoader;
import com.yi.yier.common.util.string.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.VelocityContext;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *
 * </p>
 *
 * @author Yiyuery
 * @version V1.0.0
 * @date 2020/2/24 12:03 上午
 * @modificationHistory=========================逻辑或功能性重大变更记录
 * @modify By: {修改人}  2020/2/24
 * @modify reason: {方法名}:{原因}
 * ...
 */
@Slf4j
public class DefaultTemplateContextBuilder implements ITemplateContextBuilder {

    @Override
    public <T> T getTemplateContext(GenCodeParam genCodeParam, String domainModelNameUpper, Class<T> clazz) {
        T data = null;
        try {
            data = clazz.newInstance();
            Method put = null;
            List<Method> methods = Arrays.asList(data.getClass().getMethods())
                    .stream().filter(p -> p.getName().equals("put")).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(methods)) {
                return data;
            }
            put = methods.get(0);
            put.setAccessible(true);
            if (data instanceof HashMap || data instanceof VelocityContext) {
                //注释信息补充
                String dateFormat = PropertiesLoader.getPropertyOrDefault(PropertyConstant.YIER_GEN_PROP_NOTE_FORMAT, "yyyy/MM/dd");
                put.invoke(data, "author", PropertiesLoader.getProperty(PropertyConstant.YIER_GEN_PROP_NOTE_AUTH));
                put.invoke(data, "create_time", new SimpleDateFormat(dateFormat).format(new Date()));

                //动态参数注入
                Map<String, String> propMap = PropertiesLoader.getPropMap();
                Iterator<Map.Entry<String, String>> iterator = propMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, String> next = iterator.next();
                    String sign = "";
                    if (StringUtils.isNotEmpty(genCodeParam.getSign())) {
                        sign = genCodeParam.getSign();
                    }
                    put.invoke(data, "sign", sign);
                    if (next.getKey().contains("-") && next.getKey().startsWith(PropertyConstant.YIER_GEN_PROP_PREFIX) ) {
                        put.invoke(data, next.getKey().substring(PropertyConstant.YIER_GEN_PROP_PREFIX.length()+1)
                                        .replace("-","_"),
                                PropertiesLoader.getProperty(next.getKey()).replace("{sign}", genCodeParam.getSign()));
                    }
                }
                put.invoke(data, PropertiesLoader.getProperty(PropertyConstant.YIER_GEN_PROP_TEMPLATE_DEFAULT_KEY_DOMAIN_MODEL_NAME_UPPER),
                        domainModelNameUpper);
                put.invoke(data, PropertiesLoader.getProperty(PropertyConstant.YIER_GEN_PROP_TEMPLATE_DEFAULT_KEY_DOMAIN_MODEL_NAME_LOWER),
                        CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, domainModelNameUpper));
            }
        } catch (Exception e) {
            log.error("constants 字段 反射解析失败！");
        }
        return data;
    }

}
